package riofrio;

import java.util.Iterator;
import java.util.Objects;

/**
 * A walk that starts at the root and explores as far as possible along each branch before backtracking.
 * 
 * @author Victor Hugo Herrera Maldonado
 */
public class DepthFirstWalk<T> extends AbstractTreeWalk<T>{
    
    /**
     * Order of the iteration of depth-first walk.
     */
    public enum Order{
        /**
         * The node is visited before its children.
         */
        PRE_ORDER,
        
        /**
         * The node is visited after its children.
         */
        POST_ORDER;
    }
    
    private final Order order;

    /**
     * Creates an instance of this walk for the specified node with the specified order.
     * 
     * @param node TreeNode to walk.
     * @param order The order or the walk.
     */
    public DepthFirstWalk(TreeNode<T> node, Order order) {
        super(node);
        Objects.requireNonNull(order, "order is null");
        this.order=order;
    }
    
    @Override
    public Iterator<TreeNode<T>> iterator() {
        Iterator<TreeNode<T>> iterator=null;
        assert order != null;
        switch(order) {
            case POST_ORDER:
                iterator=new PostOrderDepthFirstWalkIterator<>(getNode());
                break;
            case PRE_ORDER:
                iterator=new PreOrderDepthFirstWalkIterator<>(getNode());
                break;
            default:
                throw new AssertionError();
        }
        return iterator;
    }

}
